#include <iostream>
#include <memory>

void foo(std::shared_ptr<int> i)
{
	(*i)++;
}

int test_share_ptr()
{
	// auto pointer = new int(10); // illegal, no direct assignment
	// Constructed a std::shared_ptr
	auto pointer = std::make_shared<int>(10);
	foo(pointer);
	std::cout << *pointer << std::endl; // 11
	// The shared_ptr will be destructed before leaving the scope



	// auto pointer = std::make_shared<int>(10);
	auto pointer2 = pointer; // 引用计数 +1
	auto pointer3 = pointer; // 引用计数 +1
	int *p = pointer.get(); // 这样不会增加引用计数
	std::cout << "pointer.use_count() = " << pointer.use_count() << std::endl; // 3
	std::cout << "pointer2.use_count() = " << pointer2.use_count() << std::endl; // 3
	std::cout << "pointer3.use_count() = " << pointer3.use_count() << std::endl; // 3

	// 通过 reset() 来减少一个引用计数
	pointer2.reset();

	std::cout << "reset pointer2:" << std::endl;
	std::cout << "pointer.use_count() = " << pointer.use_count() << std::endl; // 2
	std::cout << "pointer2.use_count() = " << pointer2.use_count() << std::endl; // 0, pointer2 已 reset
	std::cout << "pointer3.use_count() = " << pointer3.use_count() << std::endl; // 2

	pointer3.reset();

	std::cout << "reset pointer3:" << std::endl;
	std::cout << "pointer.use_count() = " << pointer.use_count() << std::endl; // 1
	std::cout << "pointer2.use_count() = " << pointer2.use_count() << std::endl; // 0
	std::cout << "pointer3.use_count() = " << pointer3.use_count() << std::endl; // 0, pointer3 已 reset


	return 0; 
}






struct Foo {
	Foo() { std::cout << "Foo::Foo" << std::endl; }
	~Foo() { std::cout << "Foo::~Foo" << std::endl; }
	void foo() { std::cout << "Foo::foo" << std::endl; }
};
void f(const Foo &) {
	std::cout << "f(const Foo&)" << std::endl;
}
void test_unique_ptr() {

	std::unique_ptr<int> pointer = std::make_unique<int>(10); // make_unique 从 C++14 引入
	// std::unique_ptr<int> pointer2 = pointer; // 非法



	std::unique_ptr<Foo> p1(std::make_unique<Foo>());
	// p1 不空, 输出
	if (p1) {
		 p1->foo(); 
	}

	{
		std::unique_ptr<Foo> p2(std::move(p1));
		// p2 不空, 输出
		f(*p2);
		// p2 不空, 输出
		if(p2) p2->foo();
		// p1 为空, 无输出
		if(p1) p1->foo();
		p1 = std::move(p2);
		// p2 为空, 无输出
		if(p2) p2->foo();
		std::cout << "p2 被销毁" << std::endl;
	}
	// p1 不空, 输出
	if (p1) p1->foo();
	// Foo 的实例会在离开作用域时被销毁

}





struct A;
struct B;
struct A {
	std::shared_ptr<B> pointer;
	~A() {
		std::cout << "A 被销毁" << std::endl;
	}
};
struct B {
	std::shared_ptr<A> pointer;
	~B() {
		std::cout << "B 被销毁" << std::endl;
	}
};
void test_cycle_reference_ptr() {
	// 循环引用，要用weak_ptr
	auto a = std::make_shared<A>();
	auto b = std::make_shared<B>();
	a->pointer = b;
	b->pointer = a;
}


struct C;
struct D;
struct C {
	std::weak_ptr<D> pointer;
	~C() {
		std::cout << "C weak被销毁" << std::endl;
	}
};
struct D {
	std::weak_ptr<C> pointer;
	~D() {
		std::cout << "D weak被销毁" << std::endl;
	}
};
std::weak_ptr<int> gw;
void weak_ptr_observe()
{
    std::cout << "use_count == " << gw.use_count() << ": ";
    if (auto spt = gw.lock()) { // Has to be copied into a shared_ptr before usage
		std::cout << *spt << "\n";
    } else {
        std::cout << "gw is expired\n";
    }
}
void test_weak_ptr() {


	{
        auto sp = std::make_shared<int>(42);
		gw = sp;
		weak_ptr_observe();
    }
	std::cout << "weak指针 是否过期: " << gw.expired() << std::endl;  // true表示已被销毁，否则为false
	weak_ptr_observe();




	auto a = std::make_shared<C>();
	auto b = std::make_shared<D>();
	a->pointer = b;
	b->pointer = a;

}




int main()
{
	//test_share_ptr();

	//test_unique_ptr();

	//test_cycle_reference_ptr();

	test_weak_ptr();
}